package com.demo.algorithm.demo3;

import cn.hutool.core.collection.CollectionUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 有多个任务，一个执行错误，其他都应该取消。请用程序来模拟。
 * </p>
 *
 * @author yanyg
 * @date 2024/2/15 22:12
 */
public class TaskDemo {
    public static class MyTask extends Thread {
        /**
         * 任务名称
         */
        String taskName;
        /**
         * 执行成功或失败
         */
        Boolean success;
        /**
         * 毫秒
         */
        Long spentTime;
        /**
         * 管理线程
         */
        Boss boss;
        /**
         * 取消状态
         */
        Boolean canceling = false;
        /**
         * 执行结果
         */
        Result result;


        public MyTask(String taskName, Boolean success, Long spentTime, Boss boss) {
            this.taskName = taskName;
            this.success = success;
            this.spentTime = spentTime;
            this.boss = boss;
        }

        @Override
        public void run() {
            try {
                // 每100毫秒检查一次
                Long internal = 100L;
                Long total = 0L;
                for (; ;) {
                    // 睡眠
                    Thread.sleep(internal);
                    total = total + internal;
                    if (total >= spentTime) {
                        result = success ? Result.SUCCESS : Result.FAIL;
                        System.out.println(taskName + "执行完成" + result);
                        break;
                    }

                    // 判断任务是否需要取消
                    if (canceling) {
                        cancel();
                        result = Result.CANCEL;
                        canceling = false;
                        System.out.println(taskName + "取消执行" + result);
                        break;
                    }
                }

                // boss 处理资源等
                boss.endTask(this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public void cancel() throws InterruptedException {
            System.out.println(this.taskName + "回滚开始");
            synchronized (this) {
                Thread.sleep(2000);
            }
            System.out.println(this.taskName + "回滚结束");
        }
    }

    public static void main(String[] args) {
        Boss boss = new Boss();
        MyTask task1 = new MyTask("task1", true, 4000L, boss);
        MyTask task2 = new MyTask("task2", false, 2000L, boss);
        MyTask task3 = new MyTask("task3", true, 60000L, boss);
        boss.addTask(task1);
        boss.addTask(task2);
        boss.addTask(task3);
        boss.start();
    }

    public enum Result {
        CANCEL, SUCCESS, FAIL;
    }

    public static class Boss extends Thread {
        public List<MyTask> taskList = new ArrayList<>();

        @Override
        public void run() {
            if (CollectionUtil.isNotEmpty(taskList)){
                taskList.forEach(t -> {
                    t.start();
                });
            }
        }


        public void addTask(MyTask task) {
            taskList.add(task);
        }

        public void endTask(MyTask myTask) {
            // 执行不成功
            if (!myTask.success) {
                for (MyTask task : taskList) {
                    if (myTask != task) {
                        task.canceling = true;
                    }
                }
            }
        }
    }
}
